package study.eggs.validation;

import lombok.extern.slf4j.Slf4j;
import study.eggs.utils.FieldUtils;
import study.eggs.validation.factory.ValidatorFactory;
import study.eggs.validation.validator.Validator;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
public class ValidationUtils {

    public static void validate(Object obj) {
        if (Objects.isNull(obj)) {
            log.warn("object is null");
            return;
        }
        //Step-1: 过滤掉无注解 Field
        Field[] fields = FieldUtils.getAllField(obj);
        List<Field> fieldLt = Arrays.stream(fields)
                .filter(f -> f.getAnnotation(Annotation.class) == null)
                .collect(Collectors.toList());
        if (fieldLt == null || fieldLt.isEmpty()) {
            return;
        }
        //Step-2: 遍历 Field
        for (Field field : fieldLt) {
            String name = field.getName();
            Object value = FieldUtils.getValue(obj, field);
            Annotation[] annots = field.getAnnotations();
            for (Annotation annot : annots) {
                //验证器
                Validator validator = ValidatorFactory.getValidator(annot);
                if (Objects.isNull(validator)) {
                    log.warn("Validator Null!");
                    return;
                }
                //是否支持
                if (!validator.support(field.getType())) {
                    log.warn("Validator UnSupport Type!");
                    return;
                }
                //验证
                if (value instanceof Collection) {
                    Collection col = ((Collection) value);
                    if (col.size() > 0) {
                        col.stream().forEach(e -> {
                            validator.validate(name, e, annot);
                        });
                    }
                } else {
                    validator.validate(name, value, annot);
                }
            }
        }
    }
}
